package com.elinshaw.netty4.config

import groovy.util.logging.Slf4j
import io.netty.bootstrap.Bootstrap
import io.netty.channel.*
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.nio.NioSocketChannel
import io.netty.handler.logging.LogLevel
import io.netty.handler.logging.LoggingHandler

import javax.annotation.PostConstruct
import javax.annotation.PreDestroy

@Slf4j
abstract class NettyClientTemplate {

    final private EventLoopGroup eventLoopGroup = new NioEventLoopGroup()

    abstract protected ChannelHandler[] createHandlers()

    abstract int getPort()

    abstract String getAddress()

    @PostConstruct
    void start() throws Exception {
        Bootstrap bootstrap = new Bootstrap()
        bootstrap.group(eventLoopGroup)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
                        ChannelPipeline channelPipeline = nioSocketChannel.pipeline()
                        channelPipeline.addLast(new LoggingHandler(LogLevel.INFO))
                        ChannelHandler[] handlers = createHandlers()
                        for (ChannelHandler handler : handlers) {
                            channelPipeline.addLast(handler)
                        }
                    }
                })
        ChannelFuture channelFuture = bootstrap.connect(getAddress(), getPort()).sync()
        channelFuture.channel().closeFuture().sync()
    }

    @PreDestroy
    void stop() {
        eventLoopGroup.shutdownGracefully().syncUninterruptibly()
        eventLoopGroup.shutdownGracefully().syncUninterruptibly()
    }


}
